<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    html,
    body,
    ul,
    li,
    h1 {
      width: 100%;
      box-sizing: border-box;
      margin: 0;
      padding: 0;
      list-style: none;
    }

    #box {
      width: 300px;
      height: 300px;
      border-left: 1px solid #ccc;
      border-top: 1px solid #ccc;
      margin: 100px auto;
    }

    #box ul {
      overflow: hidden;

    }

    #box li {
      width: 50px;
      height: 50px;
      border-right: 1px solid #ccc;
      border-bottom: 1px solid #ccc;
      float: left;
      text-align: center;
      line-height: 49px;
    }
  </style>
</head>

<body>
  <div id="box">
    <ul id="list">
      <li></li>
    </ul>
  </div>
  <script src="stack.js"></script>
  <script>
    const list = document.getElementById('list');
    let arr = [];
    // 随机生成迷宫
    for (let i = 0; i < 36; i++) {
      if (i === 0) {
        arr.push('<li>1</li>')
      } else {
        arr.push(`<li>${Math.random() > 0.5 ? 1 : 0}</li>`)
      }

    }

    // 指定生成迷宫
    // arr = ["1", "1", "0", "1", "1", "1", "1", "0", "0", "1", "1", "1", "1", "0", "1", "0", "1", "0", "1", "0", "0", "1", "1", "1", "0", "0", "1", "1", "1", "0", "0", "1", "0", "1", "0", "1"]
    // arr = arr.map(item => `<li>${item}</li>`)


    list.innerHTML = arr.join('');

    // 获取所有的li节点
    const lis = list.getElementsByTagName('li');
    // 根据索引计算出节点的坐标
    // 索引 / 6 的结果为纵坐标  y
    // 索引 % 6 的结果为横坐标  x
    for (let i = 0; i < lis.length; i++) {
      let x = i % 6;
      let y = Math.floor(i / 6);
      lis[i].setAttribute('x', x)
      lis[i].setAttribute('y', y)
    }
    // 根据坐标，得到dom节点
    function getDomForPoint(x, y) {
      if (x < 0 || y < 0 || x > 5 || y > 5) {
        return;
      }
      let index = y * 6 + x;
      return lis[index];
    }

    // 入栈操作
    function pushStack(x, y) {
      stack.push({ x, y })
      getDomForPoint(x, y).style.backgroundColor = 'green';
      getDomForPoint(x, y).setAttribute('flag', 1)
    }
    // 出栈操作
    function popStack(x, y) {
      stack.pop()
      getDomForPoint(x, y).style.backgroundColor = 'red';
      getDomForPoint(x, y).setAttribute('flag', 2)
    }
    // 检测坐标是否可以通行
    function round(x, y) {

      // 判断是否超如范围
      // 判断是否在栈内
      // 判断是否出过栈
      // 判断是否数字为0
      let dom = getDomForPoint(x, y);
      if (!dom) {
        return false;
      }
      if (dom.innerHTML === '0' || dom.getAttribute('flag') === '1' || dom.getAttribute('flag') === '2') {
        return false;
      }
      return { x, y };
    }

    function delay(time) {
      return new Promise((resolve) => {
        setTimeout(resolve, time);
      })
    }

    // 接收一个坐标
    // 判断是否能入栈
    async function checkTop() {
      if (stack.len() <= 0) {
        console.log('没有可以走通的路');
        return;
      }
      // 查看栈顶元素
      await delay(1000);
      let { x, y } = stack.peek()
      // 对栈顶的元素进行检测，开是否有可通行的道路
      let canGo = round(x, y - 1) || round(x + 1, y) || round(x, y + 1) || round(x - 1, y)
      if (!canGo) {
        // 出栈操作
        popStack(x, y)
      } else {
        // 对可通行的顶点进行入栈操作
        let { x, y } = canGo;
        pushStack(x, y)
        if (x === 5) {
          return;
        }
      }
      // 栈顶元素一旦更新，就检查栈顶元素
      await checkTop();
    }

    // 创建一个栈，用来存储可通行的节点
    const stack = new Stack();
    // 0,0位置的节点入栈
    pushStack(0, 0)
    checkTop();






  </script>
</body>

</html>